import axios from 'axios'
import { ElMessage } from "element-plus";
const debounce = ['doEdit']
const messageName = 'msg'
const requestTimeout = 180000
const statusName = 'code'
const successCode = [200, 0, '200', '0']
import {
    createRouter,
    createWebHashHistory,
    createWebHistory,
} from 'vue-router'

// import { url } from '../../public/config'

// window.url = url


import qs from 'qs'
// import router from '@/router'
import { isArray } from './validate'
import router from '@/router';
// import { refreshToken } from '@/api/refreshToken'
// import { gp } from '@vab'
let loadingInstance

// let refreshToking = false

// let requests = []

// 操作正常Code数组
const codeVerificationArray = isArray(successCode)
    ? [...successCode]
    : [...[successCode]]

// const CODE_MESSAGE = {
//   200: '服务器成功返回请求数据',
//   201: '新建或修改数据成功',
//   202: '一个请求已经进入后台排队(异步任务)',
//   204: '删除数据成功',
//   400: '发出信息有误',
//   401: '用户没有权限(令牌失效、用户名、密码错误、登录过期)',
//   402: '令牌过期',
//   403: '用户得到授权，但是访问是被禁止的',
//   404: '访问资源不存在',
//   406: '请求格式不可得',
//   410: '请求资源被永久删除，且不会被看到',
//   500: '服务器发生错误',
//   502: '网关错误',
//   503: '服务不可用，服务器暂时过载或维护',
//   504: '网关超时',
// }

/**
 * axios请求拦截器配置
 * @param config
 * @returns {any}
 */
const requestConf = (config) => {
    const token = localStorage.getItem('token')
    // 不规范写法 可根据setting.config.js tokenName配置随意自定义headers
    // if (token) config.headers[tokenName] = token
    config.headers['ngrok-skip-browser-warning'] = 'any-value'
    // 规范写法 不可随意自定义
    if (token) config.headers['Authorization'] = `Bearer ${token}`

    if (!config.data) {
        config.data = {} // 解决请求没有参数时添加不上Content-Type问题
    }
    // if (
    //     config.data &&
    //     config.headers['Content-Type'] ===
    //     "application/json;charset=UTF-8"
    // )
    //     config.data = qs.stringify(config.data)
    // if (debounce.some((item) => config.url.includes(item)))
    // loadingInstance = gp.$baseLoading()
    return config
}

/**
 * 刷新刷新令牌
 * @param config 过期请求配置
 * @returns {any} 返回结果
 */
// const tryRefreshToken = async (config) => {
//   if (!refreshToking) {
//     refreshToking = true
//     try {
//       const {
//         data: { token },
//       } = await refreshToken()
//       if (token) {
//         store.dispatch('user/setToken', token).then(() => { })
//         // 已经刷新了token，将所有队列中的请求进行重试
//         requests.forEach((cb) => cb(token))
//         requests = []
//         return instance(requestConf(config))
//       }
//     } catch (error) {
//       console.error('refreshToken error =>', error)
//       router.push({ path: '/login', replace: true }).then(() => { })
//     } finally {
//       refreshToking = false
//     }
//   } else {
//     return new Promise((resolve) => {
//       // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
//       requests.push(() => {
//         resolve(instance(requestConf(config)))
//       })
//     })
//   }
// }

/**
 * axios响应拦截器
 * @param config 请求配置
 * @param data response数据
 * @param status HTTP status
 * @param statusText HTTP status text
 * @returns {Promise<*|*>}
 */
const handleData = async ({ data, status, statusText }) => {
    if (loadingInstance) loadingInstance.close()
    // 若data.code存在，覆盖默认code
    let code = data && data[statusName] ? data[statusName] : status

    // 若code属于操作正常code，则status修改为200
    if (codeVerificationArray.indexOf(data[statusName]) + 1) code = 200
    switch (code) {
        case 200:
            // 业务层级错误处理，以下是假定restful有一套统一输出格式(指不管成功与否都有相应的数据格式)情况下进行处理
            // 例如响应内容：
            // 错误内容：{ code: 1, msg: '非法参数' }
            // 正确内容：{ code: 200, data: {  }, msg: '操作正常' }
            // return data
            return data
        case 10002:
            // store
            //     .dispatch('user/resetAll')
            //     .then(() =>
            localStorage.removeItem('token')
            router.push({ name: 'login', replace: true }).then(() => { })
            //     )
            break
        case 402:
            // store
            //     .dispatch('user/resetAll')
            //     .then(() =>
            //         router.push({ path: '/login', replace: true }).then(() => { })
            //     )
            break
        case 403:
            return data
        case 404:
            return data
    }
    // 异常处理
    // 若data.msg存在，覆盖默认提醒消息
    const errMsg = `${data && data[messageName]
        ? data[messageName] : statusText
        }`
    ElMessage.error(errMsg);
    // 是否显示高亮错误(与errorHandler钩子触发逻辑一致)
    // gp.$baseMessage(errMsg, 'error', 'vab-hey-message-error')
    // if (needErrorLog())
    //     addErrorLog({ message: errMsg, stack: data, isRequest: true })
    return Promise.reject(data)
}

/**
 * @description axios初始化
 */

const instance = axios.create(
    {
        baseURL: import.meta.env.VITE_APP_BASE_API,
        timeout: requestTimeout,
        headers: {
            'Content-Type': 'application/json;charset=UTF-8',
        },
        withCredentials: true
    })

/**
 * @description axios请求拦截器
 */
instance.interceptors.request.use(requestConf, (error) => {
    return Promise.reject(error)
})

/**
 * @description axios响应拦截器
 */
instance.interceptors.response.use(
    (response) => handleData(response),
    (error) => {
        const { response } = error
        if (response === undefined) {
            if (loadingInstance) loadingInstance.close()
            // gp.$baseMessage(
            //     '未可知错误，可能是因为后端不支持跨域CORS、接口地址不存在等问题引起',
            //     'error',
            //     'vab-hey-message-error'
            // )
            return {}
        } else return handleData(response)
    }
)

export default instance
